package com.fowo.api.common.mybatis.handlers;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.springframework.util.StringUtils;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collections;
import java.util.List;

/**
 * 用于处理 List&lt;Long&gt; 的 mybaits 序列化
 */
public class IdListTypeHandler extends BaseTypeHandler<List<Long>> {
    private final ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public void setNonNullParameter(PreparedStatement preparedStatement, int i, List<Long> longs, JdbcType jdbcType) throws SQLException {
        final String string;
        try {
            string = objectMapper.writeValueAsString(longs);
        } catch (JsonProcessingException e) {
            throw new SQLException("IdList 序列化错误");
        }
        preparedStatement.setString(i, string);
    }

    @Override
    public List<Long> getNullableResult(ResultSet resultSet, String s) throws SQLException {
        String string = resultSet.getString(s);
        if (StringUtils.hasText(string)) {
            try {
                if (!string.startsWith("[")) {
                    // 兼容从单选值改成的多选值
                    return Collections.singletonList(Long.valueOf(string));
                }
                return objectMapper.readValue(string, new TypeReference<List<Long>>() {});
            } catch (JsonProcessingException e) {
                throw new SQLException("IdList 反序列化错误");
            }
        }
        return null;
    }

    @Override
    public List<Long> getNullableResult(ResultSet resultSet, int i) throws SQLException {
        String string = resultSet.getString(i);
        if (StringUtils.hasText(string)) {
            try {
                return objectMapper.readValue(string, new TypeReference<List<Long>>() {});
            } catch (JsonProcessingException e) {
                throw new SQLException("IdList 反序列化错误");
            }
        }
        return null;
    }

    @Override
    public List<Long> getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
        String string = callableStatement.getString(i);
        if (StringUtils.hasText(string)) {
            try {
                return objectMapper.readValue(string, new TypeReference<List<Long>>() {});
            } catch (JsonProcessingException e) {
                throw new SQLException("IdList 反序列化错误");
            }
        }
        return null;
    }
}
